home *** CD-ROM | disk | FTP | other *** search
/ APDL Eductation Resources / APDL Eductation Resources.iso / programs / graphics / gif2rpc / source / s / map8_accur < prev    next >
Encoding:
Text File  |  1995-12-29  |  4.7 KB  |  148 lines

  1. ; map8_accurate.s
  2. ; MACHINE:     RISC OS
  3. ; LANGUAGE:    OBJASM assembler
  4. ; AUTHOR:      Cy Booker, cy@cheepnis.demon.co.uk
  5. ; LICENSE:     FreeWare, Copyright (c) Cy Booker 1996
  6. ; PURPOSE:     Given an arbitary 48-bit colour, what is the closest 8-bit colour number?
  7. ;
  8. ; the weights we want are:
  9. ;       Red     * 0.212671   * 14 ~=  3 
  10. ;       Green   * 0.715160   * 14 ~= 10 
  11. ;       Blue    * 0.072169   * 14 ~=  1
  12. ;
  13. ; error in using the approximation {3/14, 10/14, 1/14} is < 0.000001 !
  14. ;
  15.  
  16. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  17.  
  18. bits    * 16                    ; number of bits per primary
  19.  
  20. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  21.  
  22. ; in middle we have |intensity-difference| <-- 2^|bits| - 1
  23. ; (pathalogical case).  Ordinarily can assume |diff| <= 2^|bits - 1|
  24. ;
  25. ; maximum distance is (2^|bits|-1)^2 * 3 * 14
  26. ; we want this to be less than 2^32 so can work with 32-bit unsigned integers
  27. ;
  28. ; so for arbitary |bits| of colour intensity we end out with
  29. ;       (2^|bits|-1)^2 * 3 * 14 / (2^n) < 2^32
  30. ;       n.log2 > -32.log2 + log((2^|bits|-1)^2 * 3 * 14)
  31. ;       n.log2 > -32.log2 + 2.|bits|.log2 + log(3 * 14)
  32. ;       n > 2.|bits| - 32 + log(3*14)/log2
  33. ;       n > 2.|bits| - 26.6
  34. ; so set shift (right) to 2*bits - 26
  35.  
  36.  
  37. shift   * (2 * bits) - 26
  38.         [ shift < 0
  39. shift   * 0                             ; but no need for negative shifts!
  40.         ]
  41.  
  42.  
  43. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  44.  
  45.  
  46.         GET     OS:Hdr.os
  47.  
  48.  
  49.  
  50. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  51.  
  52.         MACRO
  53. $label  Op1Shift        $op1, $dest, $src, $shift
  54.         [ ($shift) = 0
  55.                 $op1    $dest, $src
  56.         |
  57.                 [ ($shift) < 0
  58.                         $op1    $dest, $src, LSL #-($shift)
  59.                 |
  60.                         $op1    $dest, $src, LSR #($shift)
  61.                 ]
  62.         ]
  63.         MEND
  64.  
  65.         MACRO
  66. $label  Op2Shift        $op2, $dest, $srca, $srcb, $shift
  67.         [ ($shift) = 0
  68.                 $op2    $dest, $srca, $srcb
  69.         |
  70.                 [ ($shift) < 0
  71.                         $op2    $dest, $srca, $srcb, LSL #-($shift)
  72.                 |
  73.                         $op2    $dest, $srca, $srcb, LSR #($shift)
  74.                 ]
  75.         ]
  76.         MEND
  77.  
  78.  
  79. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  80.  
  81. ;
  82.  
  83.         EXPORT  map_scaled_rgb_to_palette_index
  84.  
  85.         AREA |ARM$$code|, CODE, READONLY
  86.  
  87. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  88. ;
  89. ; In    R0 -> structure
  90. ;               structure[3] = pointer to array of {red, green, blue}
  91. ;               structure[4] = number of entries in array (>= 1)
  92. ;       R1 = red nominally [0, 0xffff], but clipped as necessary
  93. ;       R2 = green nominally [0, 0xffff], but clipped as necessary
  94. ;       R3 = blue nominally [0, 0xffff], but clipped as necessary
  95. ; Out   R0 <-- index into array
  96. ;       structure[0] = error in approximating red intensity
  97. ;       structure[1] = error in approximating green intensity
  98. ;       structure[2] = error in approximating blue intensity
  99. ;
  100.  
  101.         ROUT
  102.  
  103. map_scaled_rgb_to_palette_index
  104.  
  105. str     RN      a1
  106. red     RN      a2
  107. grn     RN      a3
  108. blu     RN      a4
  109. r       RN      v1              ; r < g
  110. g       RN      v2              ; g < b
  111. b       RN      v3
  112. dmin    RN      v4
  113. dist    RN      v5
  114. palette RN      v6
  115. best    RN      ip              ; implicit != str
  116. i       RN      str
  117. t       RN      lr
  118.  
  119.                 STMFD   sp!, {a1, v1-v6, lr}
  120.                 MOV     t, #1 << bits
  121.                 CMP     red, t                               ; ensure in range [0, 0xffff]
  122.                 MOVHS   red, #0
  123.                 SUBGE   red, t, #1
  124.                 CMP     grn, t
  125.                 MOVHS   grn, #0
  126.                 SUBGE   grn, t, #1
  127.                 CMP     blu, t
  128.                 MOVHS   blu, #0
  129.                 SUBGE   blu, t, #1
  130. ;        
  131.                 MOV     dmin, #&ffffffff
  132.                 LDR     palette, [str, #4*3]
  133.                 LDR     i, [str, #4*4]
  134.                 ; for (i= ncolours; (i > 0); i--)
  135. 0
  136.                 LDMIA   palette!, {r, g, b}
  137.                 SUBS    r, r, red
  138.                 RSBLT   r, r, #0                                ; speeds up MUL instruction
  139.                 MUL     t, r, r
  140.                 [ shift > 0
  141.  Op1Shift       MOVS,   dist, t, shift                          ; dist = red * 1
  142.  Op2Shift       ADC,    dist, dist, t, shift - 1                ; dist = red * 3
  143.                 |
  144.                 ADD     dist, t, t, LSL #1                      ; dist = red * 3
  145.                 ]
  146.         
  147.                 SUBS    g, g, grn
  148.